from flask_appbuilder import expose
from myapp.models.model_dependency import Model_Dependency
from myapp.models.model_version import Model_Version
from myapp import db
from sqlalchemy import or_
import json
from .baseApi import MyappModelRestApi
from myapp.views.baseSQLA import MyappSQLAInterface as SQLAInterface

class Model_Visualization_Api(MyappModelRestApi):
    datamodel = SQLAInterface(Model_Dependency)
    route_base = '/model_visualization/api'
    
    @expose('/dependency_graph/<int:model_id>')
    def dependency_graph(self, model_id):
        """获取模型依赖关系图数据"""
        dependencies = db.session.query(Model_Dependency).filter(
            or_(Model_Dependency.source_model_id == model_id,
                Model_Dependency.target_model_id == model_id)
        ).all()
        
        nodes = []
        edges = []
        
        for dep in dependencies:
            # 构建节点和边的数据结构
            nodes.append({
                'id': dep.source_model_id,
                'label': dep.source_model.name,
                'type': dep.source_model.model_type
            })
            edges.append({
                'source': dep.source_model_id,
                'target': dep.target_model_id,
                'type': dep.dependency_type,
                'strength': dep.dependency_strength
            })
        
        return self.response(200, data={'nodes': nodes, 'edges': edges})
    
    @expose('/version_timeline/<int:model_id>')
    def version_timeline(self, model_id):
        """获取模型版本时间线"""
        versions = db.session.query(Model_Version).filter_by(
            model_id=model_id
        ).order_by(Model_Version.created_on).all()
        
        timeline_data = []
        for version in versions:
            timeline_data.append({
                'version': version.version_number,
                'date': version.created_on.isoformat(),
                'type': version.version_type,
                'changelog': version.changelog,
                'performance': json.loads(version.performance_diff)
            })
        
        return self.response(200, data=timeline_data)
    
    @expose('/batch_dependency_graph/<model_ids>', methods=['GET'])
    def batch_dependency_graph(self, model_ids):
        """获取多个模型的依赖关系图数据"""
        try:
            ids = [int(id.strip()) for id in model_ids.split(',') if id.strip().isdigit()]
            
            # 查询所有相关的依赖关系
            dependencies = db.session.query(Model_Dependency).filter(
                or_(Model_Dependency.source_model_id.in_(ids),
                    Model_Dependency.target_model_id.in_(ids))
            ).all()
            
            # 构建图数据
            nodes = set()
            edges = []
            
            for dep in dependencies:
                nodes.add(dep.source_model_id)
                nodes.add(dep.target_model_id)
                edges.append({
                    'source': dep.source_model_id,
                    'target': dep.target_model_id,
                    'type': dep.dependency_type
                })
            
            # 获取节点详细信息
            models = db.session.query(Training_Model).filter(
                Training_Model.id.in_(list(nodes))
            ).all()
            
            node_data = [{
                'id': model.id,
                'name': model.name,
                'version': model.version,
                'type': model.model_type,
                'selected': model.id in ids  # 标记哪些是用户选中的
            } for model in models]
            
            return self.response(200, **{
                'data': {
                    'nodes': node_data,
                    'edges': edges
                }
            })
            
        except Exception as e:
            return self.response(500, **{'message': str(e)})
    
    @expose('/analyze_dependencies/<int:model_id>', methods=['POST'])
    def analyze_dependencies_api(self, model_id):
        """API: 分析模型依赖关系"""
        try:
            from myapp.services.dependency_analyzer import ModelDependencyAnalyzer
            analyzer = ModelDependencyAnalyzer()
            analyzer.sync_dependencies_to_db(model_id)
            return self.response(200, message="依赖关系分析完成")
        except Exception as e:
            return self.response(500, message=f"分析失败: {str(e)}")
    
    @expose('/dependency_types')
    def get_dependency_types(self):
        """获取依赖类型列表"""
        types = [
            {'value': 'model_inheritance', 'label': '模型继承'},
            {'value': 'pipeline_flow', 'label': 'Pipeline流程'},
            {'value': 'shared_dataset', 'label': '共享数据集'},
            {'value': 'version_evolution', 'label': '版本演进'},
            {'value': 'manual', 'label': '手动配置'}
        ]
        return self.response(200, data=types)
    
    @expose('/dependency_statistics/<int:model_id>')
    def get_dependency_statistics(self, model_id):
        """获取依赖关系统计信息"""
        # 统计不同类型的依赖关系数量
        stats = db.session.query(
            Model_Dependency.dependency_type,
            db.func.count(Model_Dependency.id).label('count')
        ).filter_by(source_model_id=model_id).group_by(
            Model_Dependency.dependency_type
        ).all()
        
        result = [{'type': stat[0], 'count': stat[1]} for stat in stats]
        return self.response(200, data=result)